package br.mikhas.reflector.field;

import java.lang.reflect.Field;

/**
 * The field accessor is responsible by accessing and altering the value of a
 * field.
 * 
 * @author Mikhail Domanoski
 * 
 */
public abstract class FieldAccessor {

	/**
	 * Gets the value of the field in the target object
	 * 
	 * @param target
	 *            The target object which holds the field
	 * @return The value of the field in the object
	 */
	public abstract Object get(Object target);

	/**
	 * Sets the value of the field in the target object
	 * 
	 * @param target
	 *            The object which holds the field
	 * @param value
	 *            The new value of the field
	 */
	public abstract void set(Object target, Object value);

	/**
	 * Gets the most suitable {@link FieldAccessor} for the given field.
	 * 
	 * @param field
	 *            The field to get the accessor
	 * @return The most suitable accessor for the field
	 */
	public static FieldAccessor getAccessor(Field field) {
		if (UnsafeGetter.isUnsafeAvailable()) {
			return new UnsafeFieldAccessor(field);
		} else {
			return new ReflectionFieldAccessor(field);
		}
	}
}
